  ---@diagnostic disable: undefined-field, param-type-mismatch
local extension=Package("xiaobai-thirteen")
extension.extensionName="xiaobai"

Fk:loadTranslationTable{
  ["xiaobai-thirteen"]="十三届小白杯",
}
local U = require "packages/utility/utility"
local DIY = require "packages/diy_utility/diy_utility"
local function AddWinAudio(general)
  local Win = fk.CreateActiveSkill{ name = general.name.."_win_audio" }
  Win.package = extension
  Fk:addSkill(Win)
end

local premeditate = function(player, card, skill_name, proposer)
  skill_name = skill_name or ""
  proposer = proposer or player.id
  local room = player.room
  if type(card) == "table" then
    assert(not card:isVirtual() or #card.subcards == 1)
    card = card:getEffectiveId()
  end
  local name = ""
  if Fk.all_card_types["premeditate"] then
    name = "premeditate"
  elseif Fk.all_card_types["rfenghou__premeditate"] then
    name = "rfenghou__premeditate"
  end
  assert(name ~= "", "服务器未加入【蓄谋】！请联系管理员安装“江山如故”或“封侯”包")
  local xumou = Fk:cloneCard(name)
  xumou:addSubcard(card)
  room:sendLog{
    type = "#premeditate",
    from = proposer,
    to = {player.id},
  }
  player:addVirtualEquip(xumou)
  room:moveCardTo(xumou, Player.Judge, player, fk.ReasonJustMove, skill_name, nil, false, proposer, "", {proposer, player.id})
end

local wangbi_hide = General:new(extension,"xiaobai-thirteen__wangbi_hide", "wei",3)

wangbi_hide.hidden = true


local zhuanpan = fk.CreateActiveSkill{
  name = "xiaobai__zhuanpan",
  anim_type = "offensive",
  target_filter = function (self, to_select, selected, selected_cards, card, extra_data, player)
    return #selected < 3 and Fk:currentRoom():getPlayerById(to_select):getHandcardNum() > 0
  end,
  feasible = function (self, selected, selected_cards, player)
    return #selected > 0
  end,
  card_filter = Util.FalseFunc,
  on_use = function (self, room, effect)
    local recasts = {}
    local player = room:getPlayerById(effect.from)
    local tos = effect.tos
    room:sortPlayersByAction(tos, false)
    local target
    for _, pid in ipairs(effect.tos) do
      target = room:getPlayerById(pid)
      table.insert(recasts, room:askForCard(target, 1, 1, false, self.name, false, ".", "#xiaobai__zhuanpan_recast", nil, false))
    end
    local index = 1
    local withSlash = {}              ---@type ServerPlayer[]
    local withoutSlash = {}           ---@type ServerPlayer[]
    for _, pid in ipairs(effect.tos) do
      target = room:getPlayerById(pid)
      room:recastCard(recasts[index], target, self.name)
      if Fk:getCardById(recasts[index][1]).trueName == "slash" then
        table.insert(withSlash, target)
      else
        table.insert(withoutSlash, target)
      end
      index = index + 1 
    end
    local only = #withoutSlash == 1 and withoutSlash[1] ~= player
    withSlash = table.filter(withSlash, function (p)
      return not p:isNude() and not p.dead and p ~= player 
    end)
    withoutSlash = table.filter(withoutSlash, function (p)
      return not p:isNude() and not p.dead and p ~= player
    end)
    if #withSlash == 0 and (#withoutSlash == 0 or not only) then return end
    local all_choices = {"#xiaobai__zhuanpan_getEach", only and "#xiaobai__zhuanpan_getThreeCards::"..withoutSlash[1].id or "#xiaobai__zhuanpan__getThreeCards_cant"}
    local choices = {}
    if #withSlash > 0 then
      table.insert(choices, "#xiaobai__zhuanpan_getEach")
    end
    if #withoutSlash > 0 and only then
      table.insert(choices, all_choices[2])
    end
    local chosen = room:askForChoice(player, choices, self.name, "#xiaobai__zhuanpan_choose", nil, all_choices)
    if chosen == all_choices[1] then
      for _, p in ipairs(withSlash) do
        if not p.dead and not p:isNude() then
          local card = room:askForCardChosen(player, p, "he", self.name, "#xiaobai__zhuanpan_aquireOne::"..p.id)
          room:obtainCard(player, card, false, fk.ReasonPrey, player.id, self.name)
        end
      end
    else
      local t = withoutSlash[1] ---@type ServerPlayer
      if #t:getCardIds("he") <= 3 then
        room:obtainCard(player, t:getCardIds("he"), false, fk.ReasonPrey, player.id, self.name)
      else
        local cards = room:askForCardsChosen(player, t, 3, 3, "he", self.name, "#xiaobai__zhuanpan_aquireThree::"..t.id)
        room:obtainCard(player, cards, false, fk.ReasonPrey, player.id, self.name)
      end
    end
  end
}

wangbi_hide:addSkill(zhuanpan)

local quanzhu = fk.CreateViewAsSkill{
  name = "xiaobai__quanzhu",
  pattern = "peach",
  anim_type = "support",
  expand_pile = function (self, player)
    return Fk:currentRoom():getBanner("@$CenterArea") or {}
  end,
  card_filter = function (self, to_select, selected, player)
    if #selected == 4 then return false end
    local center = Fk:currentRoom():getBanner("@$CenterArea") or {}
    if not table.contains(center, to_select) then return false end
    local to_select_card = Fk:getCardById(to_select)
    for _, selectedid in ipairs(selected) do
      local c = Fk:getCardById(selectedid)  
      if c.suit == to_select_card.suit then
        return false
      end
    end
    return true
  end,
  view_as = function (self, cards, player)
    if #cards == 4 then
      local card = Fk:cloneCard("peach")
      card.skillName = self.name
      card:setMark(self.name, cards)
      return card
    end
  end,
  before_use = function (self, player, use)
    local subCards = use.card:getMark(self.name)
    local lose = 0
    for _, cid in ipairs(subCards) do
      local c = Fk:getCardById(cid)
      if c.is_damage_card then
        lose = lose+1
      end
    end
    player.room:setCardMark(use.card, "xiaobai__quanzhu_hurt", lose)
    DIY.RemoveCenterCards(player, subCards)
  end,
  enabled_at_play = function ()
    return #Fk:currentRoom():getBanner("@$CenterArea") > 0
  end,
  enabled_at_response = function (self, player, response)
    return #Fk:currentRoom():getBanner("@$CenterArea") > 0 and not response
  end,
}

local quanzhu_trigger = fk.CreateTriggerSkill{
  name = "#xiaobai__quanzhu_trigger",
  mute = true,
  events = {fk.AfterCardTargetDeclared},
  can_trigger = function (self, event, target, player, data)
    return table.contains(data.card.skillNames, quanzhu.name) and player:hasSkill(self, true, true) and target == player
  end,
  on_cost = Util.TrueFunc,
  on_use = function (self, event, target, player, use)
    local lose = use.card:getMark("xiaobai__quanzhu_hurt")
    if lose > 0 then
      local tos = TargetGroup:getRealTargets(use.tos)
      if tos then
          for _, pid in ipairs(tos) do 
            local p = player.room:getPlayerById(pid)
            player.room:loseHp(p, lose, self.name)
          end 
      end
    end
  end
}

quanzhu:addRelatedSkill(quanzhu_trigger)
quanzhu.CenterArea = true

wangbi_hide:addSkill(quanzhu)

Fk:loadTranslationTable{
  ["xiaobai-thirteen__wangbi_hide"] = "王必",
  ["#xiaobai-thirteen__wangbi_hide"] = "鉴鸠英雄",
  ["designer:xiaobai-thirteen__wangbi_hide"] = "食马者",
  ["illustrator:xiaobai-thirteen__wangbi_hide"] = "GWGYH",

  ["xiaobai__zhuanpan"] = "赚叛",
  [":xiaobai__zhuanpan"] = "出牌阶段限一次，你可以同时选择至多三名角色，令这些角色同时重铸一张手牌，然后你可以选择一项："..
                           "1.获得所有重铸【杀】的角色各一张牌；2.获得唯一没重铸【杀】的角色三张牌。",
  
  ["#xiaobai__zhuanpan_getEach"] = "获得所有重铸【杀】的角色各一张牌",
  ["#xiaobai__zhuanpan__getThreeCards_cant"] = "获得唯一没重铸【杀】的角色三张牌",
  ["#xiaobai__zhuanpan_getThreeCards"] = "获得%dest的三张牌",
  ["#xiaobai__zhuanpan_aquireOne"] = "赚叛：获得%dest的一张牌",
  ["#xiaobai__zhuanpan_aquireThree"] = "赚叛：获得%dest的三张牌",
  ["#xiaobai__zhuanpan_choose"] = "赚叛：请选择一项",
  ["#xiaobai__zhuanpan_recast"] = "赚叛：你须重铸一张手牌",

  ["xiaobai__quanzhu"] = "劝诛",
  [":xiaobai__quanzhu"] = "你可以移去中央区四张花色各不同的牌，视为使用一张【桃】，你每移去一张伤害牌，此【桃】的目标便先失去1点体力<a href=':xiaobai__special'>为何隐藏</a>。",
  ["xiaobai__special"] = "双重濒死问题",
  [":xiaobai__special"] = "触发技能的体力流失时，若体力流失的角色体力值不大于0，会出现双重濒死结算。",
}

local wangbi = General:new(extension,"xiaobai-thirteen__wangbi", "wei",3)

local zhini = fk.CreateTriggerSkill{
  name = "xiaobai__zhini",
  anim_type = "special",
  events = {fk.EventPhaseStart},
  can_trigger = function (self, event, target, player, data)
    return player:hasSkill(self) and target == player and player.phase == Player.Start
  end,
  on_cost = function (self, event, target, player, data)
    local room = player.room
    local t = room:askForChoosePlayers(player, table.map(room:getOtherPlayers(player),Util.IdMapper), 1, 1, "#xiaobai__zhini_prompt", self.name, true, false)
    if t and #t>0 then
      self.cost_data = room:getPlayerById(t[1])
      return true
    end
  end,
  on_use = function (self, event, target, player, data)
    local to = self.cost_data  ---@type ServerPlayer
    local cards
    local room = player.room
    local cardsNum = to:getHandcardNum()
    local hurt_num = 0
    local hurt_times = 0
    local has_hurt = false
    cards = room:askForCardsChosen(player, to, math.min(cardsNum, 3), math.min(cardsNum, 3), "he", self.name, "#xiaobai__zhini_show::"..to.id)
    room:showCards(cards)
    if player.dead or to.dead then return end
    for _, cid in ipairs(cards) do
      if Fk:getCardById(cid).is_damage_card then
        if hurt_num ~= -1 then
          hurt_num = hurt_num + 1
        end
        if not has_hurt then
          has_hurt = true
          hurt_times = hurt_times + 1
        end
      end
    end
    has_hurt = false
    if hurt_num >= 3 then
      room:damage{
        from = player,
        to = to,
        damage = 1,
        skillName = self.name,
      }
      hurt_num = -1
    end
    local cardsNum = to:getHandcardNum()
    room:delay(500)
    cards = room:askForCardsChosen(player, to, math.min(cardsNum, 2), math.min(cardsNum, 2), "he", self.name, "#xiaobai__zhini_recast::"..to.id)
    for _, cid in ipairs(cards) do
      if Fk:getCardById(cid).is_damage_card then
        if hurt_num ~= -1 then
          hurt_num = hurt_num + 1
        end
        if not has_hurt then
          has_hurt = true
          hurt_times = hurt_times + 1
        end
      end
    end
    
    has_hurt = false
    room:recastCard(cards, to, self.name) 
    if hurt_num >= 3 then
      room:damage{
        from = player,
        to = to,
        damage = 1,
        skillName = self.name,
      }
      hurt_num = -1
    end
    if player.dead or to.dead then return end
    local cardsNum = to:getHandcardNum()
    room:delay(500)
    cards = room:askForCardsChosen(player, to, math.min(cardsNum, 1), math.min(cardsNum, 1), "he", self.name, "#xiaobai__zhini_discard::"..to.id)
    for _, cid in ipairs(cards) do
      if Fk:getCardById(cid).is_damage_card then
        if hurt_num ~= -1 then
          hurt_num = hurt_num + 1
        end
        if not has_hurt then
          has_hurt = true
          hurt_times = hurt_times + 1
        end
      end
    end
    has_hurt = false
    room:throwCard(cards, self.name, to, player)
    if hurt_num >= 3 then
      room:damage{
        from = player,
        to = to,
        damage = 1,
        skillName = self.name,
      }
      hurt_num = -1
    end
    if hurt_times == 3 then
      to:turnOver()
    end
  end
}

wangbi:addSkill(zhini)

local zhuying_trigger = fk.CreateTriggerSkill{
  name = "#xiaobai__zhuying_trigger",
  events = {fk.EventPhaseStart},
  can_trigger = function (self, event, target, player, data)
    return player:hasSkill(self) and target == player and player.phase == Player.Finish
  end,
  on_use = function (self, event, target, player, data)
    local room = player.room
    local chooseCards = {}
    local toplayers = {}
    for _ = 1, 3, 1 do
      if player.dead then return end
      local targets = table.map(table.filter(room:getAlivePlayers(player), function(p)
        return not p:isNude() end), Util.IdMapper)
      if #targets == 0 then return end
      local tos = room:askForChoosePlayers(player, targets, 1, 1, "#xiaobai__zhuying-choose", self.name, true)
      if #tos == 0 then return end
      local to = room:getPlayerById(tos[1])
      if to ~= player then
        table.insertIfNeed(toplayers, to.id)
      end
      room:doIndicate(player.id, tos)
      local card = room:askForCardChosen(player, to, "he", self.name)
      table.insert(chooseCards, card)
      room:recastCard({card},  to, self.name)
      room:addTableMark(player, "zhuying", card)
    end
    if #toplayers == 0 then
      if room:askForSkillInvoke(player, self.name, nil, "#xiaobai__zhuying_xumou") then
        for _, cid in ipairs(chooseCards) do
          premeditate(player, cid, self.name)
        end
      end
    else
      room:sortPlayersByAction(toplayers)
      for _, pid in ipairs(toplayers) do
        local toplayer = room:getPlayerById(pid)
        local _, dat = room:askForUseViewAsSkill(toplayer, "#zhuying_viewAsSlash", "#zhuying_useSlash", true)
        if dat then
          room:setPlayerMark(player, "zhuying_viewAsResopnce", 1)
          local card = Fk.skills["#zhuying_viewAsSlash"]:viewAs(dat.cards)
          room:useCard{
            from = toplayer.id,
            tos = table.map(dat.targets, function(toId) return { toId } end),
            card = card,
            extraUse = true,
          }
          room:setPlayerMark(player, "zhuying_viewAsResopnce", 0)
        end
      end
    end
    room:setPlayerMark(player, "zhuying", 0)
  end
}

local zhuying_viewAsSlash = fk.CreateViewAsSkill{
  name = "#zhuying_viewAsSlash",
  card_filter = function (self, to_select, selected, player)
    return #selected == 0
  end,
  interaction = function (self, player)
    return UI.ComboBox{
      choices = {"slash", "fire_attack"}
    }
  end,
  view_as = function (self, cards, player)
    if #cards > 0 then
      local returnCard = Fk:cloneCard(self.interaction.data)
      returnCard:addSubcards(cards)
      returnCard.skillName = "xiaobai__zhuying"
      return returnCard
    end
  end
}
Fk:addSkill(zhuying_viewAsSlash)

local zhuying = fk.CreateViewAsSkill{
  name = "xiaobai__zhuying",
  pattern = "jink,nullification",
  expand_pile = function (self, player)
    return player:getTableMark("zhuying")
  end,
  card_filter = function (self, to_select, selected, player)
    if #selected > 0 then return false end
    local card = Fk:getCardById(to_select)
    if Exppattern:Parse(Fk.currentResponsePattern):match(card) then 
      return true
    end
  end,
  view_as = function (self, cards, player)
    if #cards == 0 then return nil end
    return Fk:getCardById(cards[1])
  end,
  enabled_at_response = function (self, player, response)
    return player:hasSkill("xiaobai__zhuying") and player:getMark("zhuying_viewAsResopnce") > 0
  end
}
zhuying:addRelatedSkill(zhuying_trigger)

wangbi:addSkill(zhuying)

Fk:loadTranslationTable{
  ["xiaobai-thirteen__wangbi"] = "王必",
  ["#xiaobai-thirteen__wangbi"] = "披棘良吏",
  ["designer:xiaobai-thirteen__wangbi"] = "复仇滚木",
  ["illustrator:xiaobai-thirteen__wangbi"] = "GWGYH",

  ["xiaobai__zhini"] = "指逆",
  [":xiaobai__zhini"] = "准备阶段，你可以选择一名其他角色并依次执行下列操作："..
                        "展示其三张牌；重铸其两张牌；弃置其一张牌，（不足则改为全部手牌）"..
                        "然后若此过程中：出现过三张伤害牌，你对其造成一点伤害；三次均出现伤害牌，其翻面。",
  ["#xiaobai__zhini_discard"] = "指逆：弃置 %dest 一张牌",
  ["#xiaobai__zhini_recast"] = "指逆：重铸 %dest 两张牌",
  ["#xiaobai__zhini_show"] = "指逆：展示 %dest 三张牌",
  ["#xiaobai__zhini_prompt"] = "指逆：选择一名角色",
  
  ["xiaobai__zhuying"] = "炴营",
  [":xiaobai__zhuying"] = "结束阶段，你可以重铸任意名角色共计三张牌，若均为你的牌，你可以依次蓄谋之；"..
                          "否则失去基本牌的角色可以将一张牌当【火攻】或火【杀】对你使用，且你可以使用被重铸的牌进行响应。",
  ["#xiaobai__zhuying_xumou"] = "炴营：是否蓄谋重铸的牌",
  ["#zhuying_useSlash"] = "炴营：你可以将一张牌当【火攻】或【杀】对 %dest 使用",
  ["#xiaobai__zhuying_trigger"] = "炴营",
  [ "#zhuying_viewAsSlash"] = "炴营",
  ["#xiaobai__zhuying-choose"] = "炴营：你可以重铸一名角色的一张牌"
}

return extension 